package com.springboot.demo.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.springboot.demo.entity.Inbox;
import com.springboot.demo.entity.PageRequest;
import com.springboot.demo.entity.PageResult;
import com.springboot.demo.entity.User;
import com.springboot.demo.exception.BusinessException;
import com.springboot.demo.mapper.InboxMapper;
import com.springboot.demo.service.InboxService;
import com.springboot.demo.utils.CommonUtils;
import com.springboot.demo.utils.Constant;
import com.springboot.demo.utils.PageUtils;
import com.springboot.demo.utils.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author wubc683
 * @desc
 * @date 2021-09-01 9:34
 */
@Service
public class InboxServiceImpl implements InboxService {
    @Autowired
    InboxMapper inboxMapper;
    @Autowired
    PageUtils pageUtils;
    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    private static String[] sortFields = {"readed", "createDate"};

    @Override
    public PageResult getMsg(Long uid, Integer readed, Integer type, Date startDate, Date endDate, String search,
                             String sort, PageRequest pageRequest) {
        // 检查readed字段
        if (readed != null && !Constant.Msg.READED.equals(readed) && !Constant.Msg.UNREADED.equals(readed)) {
            throw new BusinessException(ResponseResult.MSG_READ_STATE_ERROR);
        }
        // 检查type字段
        if (type != null && (type.compareTo(Constant.MsgType.ALARM) < 0 || type.compareTo(Constant.MsgType.SYSTEM) > 0)) {
            throw new BusinessException(ResponseResult.MSG_TYPE_ERROR);
        }
        // 检查起始日期和结束日期
        if (startDate != null && endDate != null && startDate.compareTo(endDate) > 0) {
            throw new BusinessException(ResponseResult.START_DATE_LARGER_THAN_END_DATE);
        }
        // 检查sort
        CommonUtils.checkSortValidity(sort, Arrays.asList(sortFields));
        PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize());
        List<Inbox> msgByUserId = inboxMapper.getMsg(uid, readed, type, startDate, endDate, search, sort);
        return pageUtils.getPageResult(pageRequest, new PageInfo<>(msgByUserId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAllMsg(Long uid) {
        inboxMapper.deleteMsgByUserId(uid);
    }

    @Override
    public void markAllMsgReaded(Long uid) {
        inboxMapper.updateAllMsgReadedByUserId(uid, Constant.Msg.READED);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markMsgReaded(Long uid, List<Long> msgIds) {
        // 检查消息是否属于用户
        List<Long> allMsgByUserId = inboxMapper.getAllMsgByUserId(uid);
        Set<Long> allMsg = new HashSet<>(allMsgByUserId);
        for (Long id : msgIds) {
            if (allMsg.contains(id)) {
                inboxMapper.updateMsgReadedByMsgId(id, Constant.Msg.READED);
            } else {
                throw new BusinessException(ResponseResult.USER_DO_NOT_HAVE_THIS_MSG);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMsg(Long uid, List<Long> msgIds) {
        List<Long> allMsgByUserId = inboxMapper.getAllMsgByUserId(uid);
        Set<Long> allMsg = new HashSet<>(allMsgByUserId);
        for (Long id : msgIds) {
            if (allMsg.contains(id)) {
                inboxMapper.deleteMsgById(id);
            } else {
                throw new BusinessException(ResponseResult.USER_DO_NOT_HAVE_THIS_MSG);
            }
        }
    }

    @Override
    public Inbox getMsgInfo(Long uid, Long msgId) {
        // 检查用户是否拥有此消息
        Inbox msgInfo = inboxMapper.getMsgInfo(msgId);
        if (msgInfo == null || !msgInfo.getOwnerId().equals(uid)) {
            throw new BusinessException(ResponseResult.USER_DO_NOT_HAVE_THIS_MSG);
        }
        return msgInfo;
    }

//    @Override
//    public void sendUnconfirmedMsg(User user) {
//        List<Inbox> allMsg = inboxMapper.getAllUnconfirmedMsgInfoByUserId(user.getId(), Constant.WEBSOCKETCMD.COMMON_MESSAGE);
//
//        for (int i = 0; i < allMsg.size(); i++) {
//            simpMessagingTemplate.convertAndSendToUser(user.getUsername(), Constant.WEBSOCKET_PRIVATE_ROOTINGKEY,
//                    allMsg.get(i));
//        }
//    }
}
